Preactを使ったScrapbox UserScriptのDemo (TODO app)
code:js
import('/api/code/programming-notes/Preactを使ったScrapbox_UserScriptのDemo_(TODO_app)/script.js');
変更点
dependencies
code:script.js
import {html} from '../htm@3.0.4%2Fpreact/script.js';
import {useState} from '../preact@10.5.13/hooks.js';
import register from '../preact-custom-element@4.2.1/script.js';
const App = ({page/*, todos: _todos*/}) => {
const addTodo = () => setTodos([...todos, Item ${todos.length}]);
return html`
<link href="//cdnjs.cloudflare.com/ajax/libs/bulma/0.9.2/css/bulma.min.css" rel="stylesheet" />
<div class="panel">
<${Header} name="ToDo's (${page})" />
${todos.map(todo => html`
<div class="panel-block" style="color: var(--page-text-color);" key="${todo}">
<span class="panel-icon">⬜</span>
${todo}
</div>
`)}
<div class="panel-block">
<button class="button is-link is-outlined is-fullwidth" onClick=${() => addTodo()}>
Add Todo
</button>
</div>
<${Footer}>footer content here<//>
</div>
`;
};
register(App, 'userscript-app', 'page', {shadow: true}); const Header = ({name}) => html<h1 class="panel-heading">⚛ ${name} List</h1>;
const Footer = props => html<footer ...${props} />;
document.getElementById('editor')
.insertAdjacentHTML('beforebegin', '<userscript-app page="All"></userscript-app>');
なんかAppというテンプレート的なものを作る感じ?yosider.icon
<App>がReact appでよく使われるentry pointとなるComponentですtakker.icon scrapboxだとdiv.app (もしくは#app-container)がそれに該当します
通常ならrender(<App />, document.getElmenetById('app'))みたく書いて、第2変数に指定した要素にReact appを埋め込んで実行しますが、ここでは趣向を変え、<userscript-app>というCustom Elementにしてみました <style>を別途埋め込むのが面倒だった
PageMenuボタンやPopupMenuを追加するようなUserScriptには関係ない?yosider.icon
関係ないですtakker.icon
ScrapboxのJavaScript読み込み機能を使ってReactアプリを動かしているだけです
_todosとは…?yosider.icon
todosだとlocal変数と名前がかぶってしまうので、別の名前にしただけですtakker.icon
あ、そういうことかyosider.icon
custom elementにしちゃうと、引数に文字列以外を渡せなくなるみたいなのでやめました
(すみません、Reactのこと何も知らない)
JavaScript.icon